classdef dotsTransaction
    % @class dotsTransaction
    % Portable representation of property access or method call
    % @details
    % Holds enough information to reproduce an interaction with a
    % dotsAllManagedObjects object.  Interactions include creation and
    % remobal of objects, joining and quitting of groups, property access
    % and modification, and method calls.
    % @details
    % Note that dotsTranaction objects are not "handle" objects--Matlab
    % copies them from variable to variable, rathern than passing
    % references to unique transaction objects.
    % @details
    % Indeed, for performance reasons, it's best to create a
    % dotsTransaction object and immediately convert it to a struct.  The
    % static method newTransactionStruct() does this automatically.
    % @details
    % Subsequent method calls should be accessed as static methods of the
    % dotsTransaction class, such as toString() and fromString(), rather
    % than as instance methods of a given dotsTransaction object.
    % @details
    % Thus, the dotsTransaction class serves to define the data content of
    % transactions (as properties or struct fields) and certain related
    % operations (as static methods).  It makes these ideas easy to find
    % and document.  But it is not intended to produce functional objects.
    
    
    properties
        % String describing the transaction: "create", "eliminate", "join",
        % "quit", "fetch", "forward", or "call"
        type = '';
        
        % String or numeric group identifier for object(s) that is the
        % target of the transaction
        objectGroup = '';
        
        % String unique identifier (UID) of the object that is the target
        % of the transaction
        objectUID = '';
        
        % String name of the object property to fetch or forward
        objectProperty = '';
        
        % String, numeric array, or function handle value of property
        propertyValue = '';
        
        % String name of the object method to invoke
        objectMethod = '';
        
        % String encoded cell array of method arguments
        methodArgs = ''
        
        % Numeric time when the transaction was initiated, in the time
        % frame of the machine which initiated the transaction.
        openTime = [];
        
        % Numeric time when the transaction was all done, in the time
        % frame of the machine which initiated the transaction.
        closeTime = [];
        
        % Numeric time just before the transaction's intended action was
        % begun, in the time frame of the machine carrying out the action.
        actionStartTime = [];
        
        % Numeric time just after the transaction's intended action was
        % finished, in the time frame of the machine carrying out the
        % action.
        actionEndTime = [];
        
        % String unique identifier for this dotsTransaction object
        UID = '';
    end
    
    properties (Access = private)
        % ASCII "unit separator" to substitite for quotes in nested strings
        quoteSubstitute = char(31);
    end
    
    methods (Access = private)
        function txn = dotsTransaction
        end
        
        % Convert a dotsTransaction object to an equivalent struct.
        function s = toStruct(txn)
            warning('off', 'MATLAB:structOnObject');
            s = struct(txn);
        end
    end
    
    methods (Static)
        % Create a new struct with fields that match the properties of the
        % dotsTransaction class.
        % @param varargin optional property-value pairs to assign to the
        % new struct.
        % @details
        % Use this method instead of the dotsTransaction constructor.
        % @details
        % Returns a struct with fields and default values that match those
        % of the dotsTransaction class.  @a varargin may contain pairs of
        % property names and values to be assigned to the new struct.
        function txn = newTransactionStruct(varargin)
            txnObj = dotsTransaction;
            for ii = 1:2:length(varargin)
                txnObj.(varargin{ii}) = varargin{ii+1};
            end
            txn = txnObj.toStruct;
        end
        
        % Convert a transaction struct to a string
        % @param txn dotsTransaction struct to convert to string
        % representation 
        % @details
        % Returns a string which represents all the field values of @a txn.
        % The original struct can be reproduced with fromString().
        % @details
        % As of 16 Feb. 2010, this method should no longer be needed, since
        % dotsTheMessenger can send struct-type data.  I'm leaving it in
        % since it's a handy debugging tool.
        function s = toString(txn)
            props = fieldnames(txn);
            n = length(props);
            cellSummary = cell(1, 2*n);
            for ii = 1:n
                cellSummary(2*ii-1) = props(ii);
                val = txn.(props{ii});
                strval = primitiveToString(val);
                cellSummary{2*ii} = strval;
            end
            s = sprintf('txn.%s=%s;', cellSummary{:});
        end
        
        % Reproduce a transaction struct from a string representation
        % @param txn a struct to receive the string representation
        % @param s a string which represents a dotsTransaction struct,
        % as returned from toString().
        % @details
        % Returns @a txn, with its fields set to the values encoded in
        % @a s.
        % @details
        % As of 16 Feb. 2010, this method should no longer be needed, since
        % dotsTheMessenger can send struct-type data.  I'm leaving it in
        % since it's a handy debugging tool.
        function txn = fromString(txn, s)
            eval(s);
        end
    end
end